package com.shawn;

import java.util.HashMap;
import java.util.Map;
import redis.clients.jedis.Jedis;

public class RedidReentrantLock {

	private ThreadLocal<Map<String, Integer>> local = new ThreadLocal<>();

	private Jedis jedis;

	public RedidReentrantLock(Jedis jedis) {
		this.jedis = jedis;
	}

	private boolean _lock(String key) {
		return jedis.set(key, "", "nx", "ex", 5L) != null;
	}

	private void _unlock(String key) {
		jedis.del(key);
	}

	private Map<String, Integer> currentLockers() {
		Map<String, Integer> refs = local.get();
		if (refs != null) {
			return refs;
		}
		local.set(new HashMap<>());
		return local.get();
	}


	public boolean lock(String key) {
		Map<String, Integer> refs = currentLockers();
		Integer refInt = refs.get(key);
		if (refInt != null) {
			refs.put(key, refInt + 1);
			return true;
		}
		boolean ok = _lock(key);
		if (!ok) {
			return false;
		}
		refs.put(key, 1);
		return true;
	}

	public boolean unlock(String key) {
		Map<String, Integer> refs = currentLockers();
		Integer refInt = refs.get(key);
		if (refInt == null) {
			return false;
		}
		refInt -= 1;
		if (refInt > 0) {
			refs.put(key, refInt);
		} else {
			refs.remove(key);
			this._unlock(key);
		}
		return true;
	}

}
